package com.csdn.ingo.dao.ctrip.search.dictionary.productscore;

import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;

import java.util.Set;

/**
 * @Author: ycy
 * @CreateDate: 2019/7/17 21:04
 */
public class main {


  private static final String MATCH = "match";
  private static final String SIM = "sim";
  protected static final String SCORE_DESC = "%s(%s) + ";

  public static void main(String[] args) {
//    int distance = 1988;
//
//    int maxDistance = 2000;
//    int level = 5;
//    int maxScore = 50;
//    int distanceLevel = maxDistance / level;
//    int scoreLevel = maxScore / level;
//    for (int i = 0; i < level; i++) {
//      if (distance <= distanceLevel * (i + 1)) {
//        int distanceScore = maxScore - (i * scoreLevel);
//        System.out.println(distanceScore);
//        return;
//      }
//    }

    boolean isPreMatch = false;
    boolean isPinyinPreMatch = false;
    boolean isPinyinMatch = false;
    boolean isFullMatch = false;
    boolean isAliasMatch = false;
    boolean nameMatch = false;

    //搜索词
    String keyword = "金山";
    // 搜索词语转拼音
    String keywordpinyin = CommonUtil.getPinyin(keyword.toLowerCase());

    //打分结果
    int productScore = 0;
    StringBuilder scoreDesc = new StringBuilder();

    //产品
    IndexDoc indexDoc = new IndexDoc();
    indexDoc.word = "旧金山";
    indexDoc.eName = "San Francisco";
    indexDoc.pinyin = "jiu jin shan";


    String docWord = CommonUtil.filterPinyinOrEname(indexDoc.word);
    indexDoc.pinyin = CommonUtil.getPinyin(docWord);

    String docPinyin = StringUtils.isEmpty(indexDoc.pinyin) ?
            StringUtils.EMPTY : CommonUtil.filterPinyinOrEname(indexDoc.pinyin);
    String docEname = StringUtils.isEmpty(indexDoc.eName) ?
            StringUtils.EMPTY : CommonUtil.filterPinyinOrEname(indexDoc.eName);
    String[] aliases = StringUtils.split(indexDoc.alias, ",");


    // 开头匹配
    if (StringUtils.startsWithIgnoreCase(docWord, keyword) ||
            (CommonUtil.hasEnglish(keyword)
                    && (StringUtils.startsWithIgnoreCase(docPinyin, keywordpinyin)
                    || StringUtils.startsWithIgnoreCase(docEname, keywordpinyin)))) {
      isPreMatch = true;
    }

    if (!CommonUtil.hasEnglish(keyword) && (
            StringUtils.startsWithIgnoreCase(docPinyin, keywordpinyin)
                    || StringUtils.startsWithIgnoreCase(docEname, keywordpinyin))) {
      isPinyinPreMatch = true;
    } else if (!CommonUtil.hasEnglish(keyword) && (StringUtils.containsIgnoreCase(docPinyin, keywordpinyin)
            || StringUtils.containsIgnoreCase(docEname, keywordpinyin))) {
      isPinyinMatch = true;
    }


    // 完全匹配
    if (StringUtils.equalsIgnoreCase(docWord, keyword)
            || StringUtils.equalsIgnoreCase(docEname, keyword)
            || StringUtils.equalsIgnoreCase(docPinyin, keywordpinyin)) {
      isFullMatch = true;
    }

    if (StringUtils.contains(docWord, keyword)
            || StringUtils.contains(indexDoc.pinyin, keyword)
            || StringUtils.contains(indexDoc.eName, keyword)) {
      nameMatch = true;
    }

    // 别名匹配
    if (aliases != null) {
      for (String alias : aliases) {
        alias = alias.trim();
        if (StringUtils.equalsIgnoreCase(alias, keyword)) {
          isFullMatch = true;
        } else if (StringUtils.startsWithIgnoreCase(alias, keyword)) {
          isPreMatch = true;
        } else if (StringUtils.containsIgnoreCase(alias, keyword)) {
          nameMatch = true;
        }
      }
    }


    if (isFullMatch) {
      productScore += 200;
      scoreDesc.append(String.format(SCORE_DESC, 200, MATCH));
    } else if (isPreMatch) {
      productScore += 150;
      scoreDesc.append(String.format(SCORE_DESC, 150, MATCH));
    } else if (nameMatch) {
      productScore += 100;
      scoreDesc.append(String.format(SCORE_DESC, 100, MATCH));
    } else if (isPinyinPreMatch) {
      productScore += 80;
      scoreDesc.append(String.format(SCORE_DESC, " keywordpinyin pre match ", 80));
    } else if (isPinyinMatch) {
      productScore += 60;
      scoreDesc.append(String.format(SCORE_DESC, " keywordpinyin pre match ", 60));
    }


    int similartyScore = (int) (Similarty.getSimValue(keyword, docWord) * 100);

    similartyScore += posMatchScore(keyword, indexDoc);
    similartyScore = similartyScore / 2; // 移位运算
    // 地标长度分
    if (isFullMatch || isPreMatch) {
      productScore += (10 - indexDoc.word.length());
    }
    productScore += similartyScore;
    scoreDesc.append(String.format(SCORE_DESC, similartyScore, SIM));


    //结果
    System.out.println(scoreDesc.toString() + productScore);

  }


  public static double getSimValue(String s1, String s2) {
    if (StringUtils.isEmpty(s1) || StringUtils.isEmpty(s2)) {
      return 0;
    }
    return new Similarty(s1, s2).sim();
  }


  /**
   * 位置打分
   */
  public static int posMatchScore(String keyword, IndexDoc doc) {
    int simScore = simCharacterNum(doc.word, keyword);
    if (StringUtils.isEmpty(doc.eName)) {
      return simScore;
    }
    int eNameSimScore = simCharacterNum(doc.eName, keyword);
    return simScore > eNameSimScore ? simScore : eNameSimScore;
  }

  public static int simCharacterNum(String word1, String word2) {
    if (Strings.isNullOrEmpty(word1) || Strings.isNullOrEmpty(word2)) {
      return 0;
    }

    Set<Character> characters = Sets.newHashSet();
    for (char c : word1.toCharArray()) {
      characters.add(c);
    }
    int simNum = 0;
    int wordLength = word2.length();
    for (char c : word2.toCharArray()) {
      if (characters.contains(c)) {
        simNum += wordLength;
      }
      wordLength--;
    }
    return simNum;
  }


}


class IndexDoc {

  String eName;

  String pinyin;

  String word;

  String alias;

}
